﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using System.IO;
using WCBG.ToolsForUnity.Tools;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class TimelineMake : MonoBehaviour {


    public const string TIMELINE_DATAPATH = "game_timeline/timeline_data/timelinealldata";
    public const string TIMELINE_DATA_BASEPATH = "game_timeline/timeline_single_data/";
    public const string TIMELINE_BASEPATH = "game_timeline/";

    private const string model_actorPath = "model/model_actor/";
    private const string model_storyPath = "model/model_story/";

    public string timeline_ID;



    private PlayableDirector m_playableDirector;
    public PlayableDirector playableDirector
    {
        get
        {
            if (m_playableDirector == null)
            {
                m_playableDirector = gameObject.AddComponentEx<PlayableDirector>();
            }
            return m_playableDirector;
        }
    }



    public void LoadTimelineForOld()
    {
        DisposeTimeline();

        if (string.IsNullOrEmpty(timeline_ID))
        {
            Debug.LogError("timeline id is null!");
            return;
        }

        Dictionary<string, TimelineSingleData> tlDict = LoadTimeLineDict();
        if (tlDict != null && tlDict.ContainsKey(timeline_ID))
        {
            TimelineSingleData data = tlDict[timeline_ID];
            //Debug.LogError(JsonUtility.ToJson(data));
            LoadPlayableDirector(data);
        }
    }

    public void LoadTimeline()
    {
        DisposeTimeline();

        if (string.IsNullOrEmpty(timeline_ID))
        {
            Debug.LogError("timeline id is null!");
            return;
        }

        TextAsset textAsset = Resources.Load<TextAsset>(TIMELINE_DATA_BASEPATH + "timelinedata_" + timeline_ID);
        if (textAsset == null || string.IsNullOrEmpty(textAsset.text))
            return;
        TimelineSingleData data = JsonUtility.FromJson<TimelineSingleData>(textAsset.text);

        LoadPlayableDirector(data);
    }

    public void SaveTimeline()
    {
        SaveTimelineToData();
    }

    public void DisposeTimeline()
    {
        List<Transform> list = new List<Transform>();
        for (int i = 0; i < transform.childCount; i++)
        {
            list.Add(transform.GetChild(i));
        }
        foreach (Transform target in list)
        {
            GameObject.DestroyImmediate(target.gameObject);
        }
        list.Clear();
    }

    public void DeleteTimeline()
    {
        DisposeTimeline();
        string path = Application.dataPath + "/Resources/" + TIMELINE_DATA_BASEPATH + "timelinedata_" + timeline_ID + ".json";
        if (File.Exists(path))
        {
            File.Delete(path);
            Debug.Log("删除timeline数据:" + path);
        }

#if UNITY_EDITOR
        AssetDatabase.Refresh();
#endif

    }

    private Dictionary<string, TimelineSingleData> LoadTimeLineDict()
    {
        Dictionary<string, TimelineSingleData> tlDict = new Dictionary<string, TimelineSingleData>();
        TextAsset textAsset = Resources.Load<TextAsset>(TIMELINE_DATAPATH);

        if (textAsset != null)
        {
            TimelineData tlData = JsonUtility.FromJson<TimelineData>(textAsset.text);

            for (int i = 0; i < tlData.timelineList.Count; i++)
            {
                TimelineSingleData singleData = tlData.timelineList[i];
                tlDict.Add(singleData.ID, singleData);
            }
            return tlDict;
        }
        return null;
    }

    private void LoadPlayableDirector(TimelineSingleData data)
    {
        PlayableAsset playableAsset = Resources.Load<PlayableAsset>(TIMELINE_BASEPATH + timeline_ID);
        if (playableAsset != null)
        {
            playableDirector.playableAsset = playableAsset;
        }

        Dictionary<string, PlayableBinding> pbDict = new Dictionary<string, PlayableBinding>();

        IEnumerable<PlayableBinding> Bindings = playableAsset.outputs;

        foreach (PlayableBinding bindind in Bindings)
        {
            //Debug.Log("sourceBindingType" + ", sourceObject:" + bindind.sourceObject + ", streamName:" + bindind.streamName + ", streamType:" + bindind.streamType);
            pbDict.Add(bindind.streamName, bindind);
        }

        Dictionary<string, GameObject> chacheTest = new Dictionary<string, GameObject>();

        foreach (var temp in data.trackParentList)
        {
            GameObject obj = null;
            if (chacheTest.ContainsKey(temp.objName))
            {
                obj = chacheTest[temp.objName];
            }
            else
            {
                if (temp.storyName == "Commom")
                {
                    obj = CreateObj(FileTools.CombinePath(model_storyPath, temp.objName));
                    //Debug.Log("XXXXXXXXXXXXXXXXXXXXX" + item.name);
                    //obj = StoryGameObjectPool.Instance.GetPool(item);
                    chacheTest.Add(temp.objName, obj);
                }
                else if (temp.storyName == "Actor")
                {
                    obj = CreateObj(FileTools.CombinePath(model_actorPath, temp.objName));
                    //obj = StoryGameObjectPool.Instance.GetPool(item);
                    chacheTest.Add(temp.objName, obj);
                }
                else
                {
                    string url = temp.storyName + "/";
                    //Debug.Log(url + "XXXXXXXXXXXXXXXXXX" + temp.objName);
                    obj = CreateObj(FileTools.CombinePath(url, temp.objName));
                    //obj = StoryGameObjectPool.Instance.GetPool(item);
                    chacheTest.Add(temp.objName, obj);
                }

            }

            obj.transform.SetParent(this.transform);
            obj.name = temp.objName;
            if (pbDict.ContainsKey(temp.trackName))
            {
                Object sourceObj = pbDict[temp.trackName].sourceObject;
                playableDirector.SetGenericBinding(sourceObj, obj);
                //Debug.LogError("obj:" + obj.name);
            }
            else
            {
                Debug.LogError("Get sourceObject falid!:trackname:" + temp.trackName);
            }
        }

        foreach (var temp in data.trackChildList)
        {
            if (chacheTest.ContainsKey(temp.parentName))
            {
                GameObject parentObj = chacheTest[temp.parentName];
                playableDirector.SetGenericBinding(pbDict[temp.trackName].sourceObject, parentObj.transform.FindChildEx(temp.objName).gameObject);
            }
            else
            {
                Debug.Log("Parent is null:" + temp.parentName);
            }
        }

        GameObject Audio_Parent = null;
        if (data.trackAudioList.Count > 0)
        {
            Audio_Parent = CreateObj("model/model_story/Audio_Parent");
            //Audio_Parent = StoryGameObjectPool.Instance.GetPool(item);
            Audio_Parent.name = Audio_Parent.name.Replace("(Clone)", "");
            Audio_Parent.transform.SetParent(this.transform);
        }
        foreach (var temp in data.trackAudioList)
        {
            playableDirector.SetGenericBinding(pbDict[temp.trackName].sourceObject, Audio_Parent.transform.Find(temp.objName).GetComponent<AudioSource>());
        }


    }

    private GameObject CreateObj(string path)
    {
        GameObject go = Resources.Load<GameObject>(path);
        if (go != null)
        {
            return GameObject.Instantiate(go);
        }
        return null;
    }

    private void SaveTimelineToData()
    {
        TimelineSingleData singleData = new TimelineSingleData();
        PlayableDirector director = transform.GetComponent<PlayableDirector>();
        if (director != null)
        {
            IEnumerable<PlayableBinding> Bindings = director.playableAsset.outputs;

            singleData.ID = timeline_ID;
            foreach (PlayableBinding bindind in Bindings)
            {
                Object obj = director.GetGenericBinding(bindind.sourceObject);
                if (obj != null)
                {
                    TrackData trackData = new TrackData();
                    trackData.trackName = bindind.streamName;
                    trackData.objName = obj.name;
                    GameObject objGo = obj as GameObject;
                    if (objGo)
                    {
                        TLIdentify_Parent indentify = objGo.GetComponent<TLIdentify_Parent>();
                        if (indentify != null)
                        {
                            trackData.bIsIdentify_Parent = true;
                            trackData.storyName = indentify.storyname.ToString();
                            singleData.trackParentList.Add(trackData);
                        }
                        else
                        {
                            trackData.bIsIdentify_Parent = false;
                            TLIdentify_Parent indentifyParent = objGo.GetComponentInParent<TLIdentify_Parent>();
                            if (indentifyParent != null)
                            {
                                trackData.parentName = indentifyParent.name;
                                singleData.trackChildList.Add(trackData);
                                //Debug.Log("parentName name:" + indentifyParent.name);
                            }
                        }
                    }
                    else
                    {
                        trackData.bIsIdentify_Parent = false;
                        trackData.parentName = "Audio_Parent";
                        singleData.trackAudioList.Add(trackData);
                        //Debug.Log("parentName name: Audio_Parent");
                    }
                }
            }
        }

        string jsonData = JsonUtility.ToJson(singleData);
        string path = Application.dataPath + "/Resources/"+ TIMELINE_DATA_BASEPATH;
        if (!FDirectory.Exists(path))
        {
            FDirectory.CreateDirectory(path);
        }
        string savepath = path + "timelinedata_" + timeline_ID + ".json";
        File.WriteAllText(savepath, jsonData);
        Debug.Log("保存timeline数据:" + savepath);

#if UNITY_EDITOR
        AssetDatabase.Refresh();
#endif

    }


}
